package com.wang.helloandroid.ws;

import java.net.URI;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.java_websocket.client.DefaultSSLWebSocketClientFactory;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft_17;
import org.java_websocket.handshake.ServerHandshake;
import com.wang.helloandroid.util.Encrypt;
import android.annotation.SuppressLint;
import android.util.Log;

public abstract class WSClient extends WebSocketClient {
	final static String tag = WSClient.class.getName();
	
	private static String userName;
	
	protected static Map<String, String> getHeader(String uri, String userName, String password)
	{
		Map<String, String> headers = new HashMap<String, String>();

		headers.put("Authorization", "Basic " + getAuthenticationToken(userName, password));
		headers.put("user-agent", "WebSocket Client");
		/*headers.put("Host", uri.split("://")[1].split("/")[0]);
		headers.put("Connection", "Upgrade");
		headers.put("Upgrade", "websocket");
		headers.put("Sec-WebSocket-Version", "13");
		headers.put("Sec-WebSocket-Key", Encrypt.base64Encode(UUID.randomUUID().toString()));*/

		return headers;
	}
	
	protected static String getAuthenticationToken(String username, String password)
	{
		userName = username;
		return Encrypt.base64Encode(userName + ":" + password);
	}
	
	@SuppressLint("TrulyRandom")
	public WSClient(URI uri, String userName, String password) throws NoSuchAlgorithmException, KeyManagementException {
		super(uri, new Draft_17(), getHeader(uri.toString(), userName, password), 0);
		SSLContext sc = SSLContext.getInstance("TLS");
		sc.init(null, getTrustManagers(), new java.security.SecureRandom());
		setWebSocketFactory(new DefaultSSLWebSocketClientFactory(sc));
	}
	
	public boolean isOpen()
	{
		return super.getConnection().isOpen();
	}

	public boolean isClosed()
	{
		return super.getConnection().isClosed();
	}

	@Override
	public void onOpen(ServerHandshake serverHandshake) {
		Log.i("Websocket", "Opened");
		send("{\"message\":\"Hello World\",\"username\":\"" + userName + "\"}");
	}

	@Override
	public void onClose(int i, String s, boolean b) {
		Log.i("Websocket", "Closed " + s);
	}

	@Override
	public void onError(Exception e) {
		Log.i("Websocket", "Error " + e.getMessage());
	}
	
	@Override
	public void send(String message)
	{
		super.send(Encrypt.base64Encode(message));
	}
	
	protected TrustManager[] getTrustManagers()
	{
		TrustManager[] trustAllCerts = new TrustManager[] {
			new X509TrustManager() {
				@Override
				public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType)
						throws CertificateException {
				}

				@Override
				public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType)
						throws CertificateException {
				}

				@Override
				public java.security.cert.X509Certificate[] getAcceptedIssuers() {
					return new java.security.cert.X509Certificate[] {};
				}
			}
		};

		return trustAllCerts;
	}
}
